package mjc.tds;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.Iterator;
import java.util.Arrays; 

public class TDM extends TDS<CleMethode,Info_Methode> {

	private boolean castableConflict = false;
	private boolean castableResearchDone = false;
	private ArrayList<Info_Methode> castablesFound;
	protected Info_Classe classeParente;
	
	protected String label;
	public TDM(String nomClasse) {
		super() ;
		this.label=nomClasse+"_TDM";
	}
	
	public TDM(TDM parente,String nomClasse){
		super(parente);
		this.label=nomClasse+"_TDM";
	}
	
	public TDM(TDM parente, Info_Classe _classeParente,String _nom,String nomClasse) {
		super(parente);
		this.classeParente = _classeParente;
		this.label=nomClasse+"_TDM";
	}

	public String getLabel(){
		return this.label;
	}
	
	public void removeMethode(CleMethode cleMethode){
		this.table.remove(cleMethode);
	}
	
	public ArrayList<Info_Methode> getCastablesMethodes(CleMethode cle){
		castableConflict = false;
		castablesFound = new ArrayList<Info_Methode>();
		Iterator<CleMethode> iterateur = this.table.keySet().iterator();
		while(iterateur.hasNext()){
			Info_Methode methode =  ((Info_Methode)table.get((CleMethode)iterateur.next()));
			Signature candidate = methode.getSignature();
			if(cle.getSignature().canBeCastedTo(candidate) && cle.getNom().equals(methode.getNom())){
				castablesFound.add(methode);
			}
		}
		
		if(castablesFound.size()==0 && parente != null ){
			castablesFound = this.classeParente.getTDM().getCastablesMethodes(cle);
		}
		
		castableResearchDone = true;
		return castablesFound;
	}
	
	public boolean existeCastable(){
		return (castableResearchDone && (castablesFound.size()>0) );
	}

	public boolean castablesEnConflit(){
		return (castableResearchDone && (castablesFound.size()>=2));
	}
	
	public Info_Methode getCastableMethode(CleMethode cle){
		this.getCastablesMethodes(cle);
		if(existeCastable() && !(castablesEnConflit())){
			return castablesFound.get(0);
		}
		else{
			return null;
		}
	}
	
	public Info_Methode getFirstInConflict(){
		if(this.castablesEnConflit()){
			System.out.println("Premier");
			return castablesFound.get(0);
			
		}
		else{
			System.out.println("Erreur");
			return null;
		}
	}

	public Info_Methode getSecondInConflict(){
		if(this.castablesEnConflit()){
			System.out.println("Deuxieme");
			return castablesFound.get(1);
		
		}
		else{
			System.out.println("Erreur");
			return null;
		}
	}
	
	public Info_Methode[] getAllMethods(){
		Info_Methode[] methodes = (Info_Methode[])this.table.values().toArray(new Info_Methode[0]);
		Arrays.sort(methodes, new Comparator(){
			  public int compare(Object obj1, Object obj2) {
				  if(((Info_Methode)obj1).indice<((Info_Methode)obj2).indice){
					  return -1;
				  }else if(((Info_Methode)obj1).indice>((Info_Methode)obj2).indice){
					  return 1;
				  }else
					  return 0;
			  }
		});
		return methodes;
	}
	
}

